<script setup lang="ts">
import { onMounted, ref, unref, reactive, computed, defineAsyncComponent } from 'vue'
import { useBaseApi } from '@/api/base'
import { clone, isNumber } from 'xe-utils'
import { ElMessage } from 'element-plus'
import mittBus from '@/utils/mitt'
import type { VxeGridProps, VxeTableInstance } from 'vxe-table'
import type {
  DicType,
  BusinessUIAction,
  BusinessUIFormType,
  BusinessUIQueryType,
  BusinessUITableType
} from '@/types/custom'
import { initFooterMethod, initFormatColumns, initGridProps, formatColRows } from '@/views/components/grid/libs'
import { storeToRefs } from 'pinia'
import { useAppState } from '@/stores/appState'
import { Delete, EditPen, Refresh } from '@element-plus/icons-vue'

const TemplateQuery = defineAsyncComponent(
  () => import('@/views/components/form/TemplateQuery.vue')
)

const { CustomRequest, get_business_ui } = useBaseApi()
const { mobile } = storeToRefs(useAppState())

interface Props {
  _action?: BusinessUIAction
  _params: TypedAny
  defaultParams?: TypedAny
}

interface RowType {
  created_on: string
  dep_id: string
  dep_name: string
  files: TypedAny[]
  id: string
  is_dis: boolean
  modified_on: string
  name: string
  org_id: string
  org_name: string
  own_division: string
  own_division_name: string
  own_user: string
  sex: string
}

const props = defineProps<Props>()
const emit = defineEmits(['close', 'fetch'])

// 表格
const xGrid = ref<VxeTableInstance>()
const loading = ref(false)
const params = ref<TypedAny>({})
const gridOptions = ref<VxeGridProps<RowType>>({})
// 表格
const uiTable = ref<BusinessUITableType | undefined>()
// 表格
const uiForm = ref<BusinessUIFormType | undefined>()
// 查询栏
const uiQuery = ref<BusinessUIQueryType | undefined>()
// 表单字典
const dicTable = ref<DicType[]>([])
// 查询字典
const dicQuery = ref<DicType[]>([])
// 按钮配置
const uiActions = ref<BusinessUIAction[]>([])
// 表格分页
const gridPage = reactive({
  total: 0,
  page: 1,
  pageSize: 50
})
const current = ref('select')
const options = [
  { label: '全部', value: 'select' },
  { label: '已选择', value: 'selected' }
]
const items = ref<RowType[]>([])
const selected = ref<RowType[]>([])

const gridData = computed(() => {
  if (current.value === 'selected') {
    return selected.value
  } else {
    return items.value
  }
})

/**
 * 格式化参数
 */
const onFormatParams = () => {
  if (props._action && props.defaultParams) {
    params.value = {}
    const default_value_parse = props._action.default_value_parse
    if (Object.keys(default_value_parse).length) {
      for (const k in default_value_parse) {
        params.value[k] = props.defaultParams[k] || default_value_parse[k]
      }
    } else {
      params.value = clone(props.defaultParams, true)
    }
  }
}

/**
 * 获取业务详情
 */
const onFetchBusiness = async () => {
  loading.value = true
  const business_id = props._action?.business_id
  if (!business_id) return Promise.reject(false)
  const { data } = await get_business_ui(business_id)

  if (!data.ui_table) return Promise.reject(false)

  uiTable.value = data.ui_table
  uiQuery.value = data.ui_query
  uiForm.value = data.ui_form
  dicTable.value = data.dic_table || []
  dicQuery.value = data.dic_query || []
  uiActions.value = data.actions || []

  // 加载数据
  // await onFetch()

  // 格式化表格配置
  gridOptions.value = initGridProps({
    uiTable: data.ui_table
  })

  const cols = await initFormatColumns({
    uiForm: data.ui_form,
    uiTable: data.ui_table,
    dicTable: data.dic_table,
    uiActions: data.actions
  })

  // 初始化表尾合计
  initFooterMethod(unref(gridOptions), cols)

  gridOptions.value.columns = [
    {
      type: 'checkbox',
      width: 50
    },
    ...cols
  ]

  loading.value = false

}

/**
 * 查询数据
 * @param slotParams 查询参数
 */
const onFetch = async (slotParams?: TypedAny) => {
  const table = unref(uiTable)
  if (!table) return Promise.reject(false)

  loading.value = true

  const param = Object.assign({}, gridPage, slotParams, unref(params))

  const { data } = await CustomRequest<{ selected: RowType[]; items: RowType[]; total: number }>({
    url: table.api,
    method: table.method,
    params: table.method === 'get' ? param : unref(params),
    data: table.method === 'post' ? param : undefined
  })

  // 总数
  if (data && isNumber(data.total)) gridPage.total = data.total

  const list = data.items || []
  formatColRows({
    rows: list,
    uiTable: uiTable.value,
    uiForm: uiForm.value,
    dicTable: dicTable.value
  })
  items.value = list

  if (!selected.value.length) selected.value = data.selected || []

  // 赋值选中
  onRadioChange()

  loading.value = false
}

/**
 * 保存
 */
const onSave = async () => {
  if (xGrid.value) {
    const param = unref(params)
    return CustomRequest({
      url: uiTable.value?.api,
      method: 'put',
      params: param,
      data: { rows: unref(selected) }
    }).then(({ data }) => {
      if (data && data.forms && data.forms.length) {
        // 把数据发送给父级
        mittBus.emit('onUpdateParent', data)
      }
      ElMessage.success('保存成功')
      emit('fetch')
      return data
    })
  } else {
    return Promise.resolve()
  }
}

const getLabel = (option: SelectOptionType) => {
  return option.value === 'selected'
    ? `${option.label}（${selected.value.length}）`
    : `${option.label}（${gridPage.total}）`
}

const onCheckboxChange = () => {
  const $grid = xGrid.value
  if (!$grid) return
  const records = $grid.getCheckboxRecords(true)

  if (current.value === 'selected') {
    selected.value = selected.value.filter((f) => records.some((s) => s.id === f.id))
  } else {
    const nots = selected.value.filter((f) => !items.value.some((s) => s.id === f.id))
    selected.value = [...records, ...nots]
  }
}

const onDelete = () => {
  const $grid = xGrid.value
  if (!$grid) return

  selected.value.splice(0)
  $grid.clearCheckboxRow()
}

const onRadioChange = () => {
  setTimeout(() => {
    // 赋值选中
    const $grid = xGrid.value
    if ($grid) $grid.setCheckboxRow(selected.value, true)
  }, 150)
}

const onAction = () => {}

const onRefresh = () => {
  selected.value.splice(0)
  onFetch()
}

onMounted(() => {
  onFormatParams()
  onFetchBusiness()
})

defineExpose({ onSave })
</script>

<template>
  <div class="h100 flex flex-column">
    <TemplateQuery
      v-if="uiTable"
      :value="true"
      ref="queryRef"
      :ui-query="uiQuery"
      :ui-actions="uiActions"
      :dic-query="dicQuery"
      :right-spacing="0"
      @action="onAction"
      @fetch="onFetch"
    >
      <template #query_default>
        <el-radio-group v-model="current" @change="onRadioChange">
          <el-radio-button
            v-for="(option, index) in options"
            :key="index"
            :value="option.value"
            :label="getLabel(option)"
          />
        </el-radio-group>
        <el-button :icon="Delete" type="danger" @click="onDelete">清空选中</el-button>
        <el-button :icon="EditPen" type="success" @click="onSave">保存选中</el-button>
      </template>
    </TemplateQuery>
    <div class="flex-grow relative">
      <vxe-grid
        ref="xGrid"
        v-bind="gridOptions"
        height="auto"
        :data="gridData"
        :loading="loading"
        append-to-body
        class="table-grid"
        @checkbox-change="onCheckboxChange"
        @checkbox-all="onCheckboxChange"
      >
        <!-- 标签 -->
        <template #el_tag="{ row, column }">
          <el-tag :type="row[`${column.field}_display_type`] || 'info'">
            {{ row[column.field] }}
          </el-tag>
        </template>
        <!-- pager 插槽-->
        <template #pager v-if="uiTable?.pagination && current === 'select'">
          <vxe-pager
            :layouts="
              mobile
                ? ['PrevJump', 'PrevPage', 'Number', 'NextPage', 'Total']
                : [
                    'Sizes',
                    'PrevJump',
                    'PrevPage',
                    'Number',
                    'NextPage',
                    'NextJump',
                    'FullJump',
                    'Total'
                  ]
            "
            v-model:current-page="gridPage.page"
            v-model:page-size="gridPage.pageSize"
            :total="gridPage.total"
            @page-change="onFetch()"
          >
          </vxe-pager>
        </template>
      </vxe-grid>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.table-grid {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}
</style>
